package com.nulldev.util.net.irc;

import java.util.LinkedList;
import java.util.List;

import com.nulldev.util.string.ReadOnlyStringProperty;
import com.nulldev.util.string.ReadOnlyStringWrapper;
import com.nulldev.util.threading.legacy.ThreadExecutor;

public class Channel implements Entity {
	private Server server;
	private ReadOnlyStringWrapper name = new ReadOnlyStringWrapper();

	private ReadOnlyStringWrapper topic = new ReadOnlyStringWrapper();
	private User topicAuthor;
	private long topicTimestamp;

	private List<User> users = new LinkedList<User>();

	private List<Mode> bans = new LinkedList<Mode>();
	private List<Mode> invites = new LinkedList<Mode>();
	private List<Mode> excepts = new LinkedList<Mode>();

	public Channel(Server server, String name) {
		this.server = server;
		this.name.set(name);
	}

	public Server getServer() {
		return server;
	}

	public Server getServerProperty() {
		return server;
	}

	public String getName() {
		return name.get();
	}

	public ReadOnlyStringProperty getNameProperty() {
		return name.getReadOnlyProperty();
	}

	public String getTopic() {
		return topic.get();
	}

	public ReadOnlyStringProperty getTopicProperty() {
		return topic.getReadOnlyProperty();
	}

	public void setTopic(String topic) {
		this.topic.set(topic);
	}

	public List<User> getUsers() {
		return users;
	}

	public void addUser(final User user) {
		ThreadExecutor.execute(new Runnable() {
			@Override
			public void run() {
				if (!users.contains(user)) {
					users.add(user);
				}
			}
		});
	}

	public void removeUser(final User user) {
		ThreadExecutor.execute(new Runnable() {
			@Override
			public void run() {
				users.remove(user);
			}
		});
	}

	public List<User> getUsersProperty() {
		return users;
	}

	public User getTopicAuthor() {
		return topicAuthor;
	}

	public void setTopicAuthor(User author) {
		topicAuthor = author;
	}

	public User getTopicAuthorProperty() {
		return topicAuthor;
	}

	public long getTopicTimestamp() {
		return topicTimestamp;
	}

	public void setTopicTimestamp(long ts) {
		topicTimestamp = ts;
	}

	public long getTopicTimestampProperty() {
		return topicTimestamp;
	}

	public void clearData() {
		topic.set(null);
		users.clear();
	}

	public List<Mode> getBans() {
		return bans;
	}

	public List<Mode> getBansProperty() {
		return bans;
	}

	public List<Mode> getInvites() {
		return invites;
	}

	public List<Mode> getInvitesProperty() {
		return invites;
	}

	public List<Mode> getExcepts() {
		return excepts;
	}

	public List<Mode> getExceptsProperty() {
		return excepts;
	}

	@Override
	public boolean equals(Object o) {
		if (super.equals(o)) {
			return true;
		}
		if (o instanceof Channel) {
			Channel channel = (Channel) o;
			return channel.getServer().equals(getServer()) && channel.getName().equalsIgnoreCase(getName());
		}
		return false;
	}
}
